(function() {

  var events = require('events');
  var util = require('util');
  var ElasticSearchClient = require('elasticsearchclient');
  var Logger = require(__dirname + '/../log/logger');
  var JsonReader = require(__dirname + '/../util/jsonReader');
  var config = JsonReader.read(__dirname + '/../../config/search/searchConfig.json');
  var searchUtil = require('./util');

  var serverOptions = {
    host : config.elServerHost,
    port : config.elServerPort
  };

  var IndexBuilder = function() {
    this.logger = Logger.getLogger();
    this.searchClient = new ElasticSearchClient(serverOptions);
    this.logger = Logger.getLogger();
    events.EventEmitter.call(this);
  };

  IndexBuilder.prototype.constructor = IndexBuilder;
  IndexBuilder.prototype.searchClient = null;
  IndexBuilder.prototype.logger = null;

  util.inherits(IndexBuilder, events.EventEmitter);

  IndexBuilder.prototype.buildIndex = function(type, document, callback) {
    var self = this;
    // check if document has id, if no id return error
    if (document.id == null || document.id.trim() == '') {
      var errorResult = searchUtil.composeErrorResult('Id is required.', this.logger);
      if (typeof callback == 'function') {
        callback(null, errorResult);
      } else {
        self.emit('finish', errorResult);
      }
      return;
    }

    // only support user/account/event
    if (!searchUtil.isValidType(type)) {
      var errorResult = searchUtil.composeErrorResult('Type should be in [user, account, event].', this.logger);
      if (typeof callback == 'function') {
        callback(null, errorResult);
      } else {
        self.emit('finish', errorResult);
      }
      return;
    }

    // password should not be stored
    delete document['password'];

    // save document
    this.searchClient.index(config.indexName, type, document, document.id, null).on('data', function(data) {
      var indexResult = _parseSuccessResult(data);
      if (typeof callback == 'function') {
        callback(null, indexResult);
      } else {
        self.emit('finish', indexResult);
      }
    }).on('error', function(error) {
      if (typeof callback == 'function') {
        callback(error);
      } else {
        self.emit('error', error);
      }
    }).exec();
  };

  IndexBuilder.prototype.deleteIndex = function(type, documentId, callback) {
    var self = this;
    // check if document has id, if no id return error
    if (documentId == null) {
      var errorResult = searchUtil.composeErrorResult('Id is required.', this.logger);
      if (typeof callback == 'function') {
        callback(null, errorResult);
      } else {
        self.emit('finish', errorResult);
      }
      return;
    }

    // only support user/account/event
    if (!searchUtil.isValidType(type)) {
      var errorResult = searchUtil.composeErrorResult('Type should be in [user, account, event].', this.logger);
      if (typeof callback == 'function') {
        callback(null, errorResult);
      } else {
        self.emit('finish', errorResult);
      }
      return;
    }

    // delete document
    this.searchClient.deleteDocument(config.indexName, type, documentId, null, callback).on('data', function(data) {
      var indexResult = _parseSuccessResult(data);
      if (typeof callback == 'function') {
        callback(null, indexResult);
      } else {
        self.emit('finish', indexResult);
      }
    }).on('error', function(error) {
      if (typeof callback == 'function') {
        callback(error);
      } else {
        self.emit('error', error);
      }
    }).exec();
  };

  function _parseSuccessResult(indexResultStr) {
    var indexResult = JSON.parse(indexResultStr);
    console.log(indexResult);
    var id = indexResult['_id'];
    var result = {};
    result['data'] = {};
    result['data']['id'] = id;
    return result;
  }

  module.exports = IndexBuilder;

})();
